# Function: Input log file(s) and output collision and decel feature
# Output format: Time,type,vehicle,vehicle
# Param:
#     1. If you want to do single file processing, then use -i and -o to specify input and output file,
#        for example extract_feature -i logs.txt -o feature.csv.
#     2. If you want to do batch processing, then use --indir and --outdir to specify input and output dir,
#        for example extract_feature --indir ../data/input -outdir ../data/output

import os
import optparse
import csv

# io operation
def parse_line(line, delimiter):
    new_line = []
    old_line = line.strip().split(delimiter)
    for item in old_line:
        new_line.append(item.strip('\"'))
    return new_line

def read_data(filename, delimiter=',', parse_func=parse_line):
    ret = []
    with open(filename, "rb") as f:
        for line in f:
            ret.append(parse_func(line, delimiter))
    return ret

def write_csv(filename, data, headers=''):
    with open(filename, "wb") as f:
        f_csv = csv.writer(f)
        if headers:
            f_csv.writerow(headers)
        for row in data:
            f_csv.writerow(row)

# feature extraction
def extract_feature(f, log_time, feature_data):
    for line in f:
        if line[0] == 'Warning:' and line[4] == 'collision':
            entry = list()
            entry.append(log_time)
            entry.append('collision')
            line[3] = line[3].strip(';')
            line[3] = line[3].strip('\'')
            entry.append(line[3])
            line[6] = line[6].strip(',')
            line[6] = line[6].strip('\'')
            entry.append(line[6])
            feature_data.append(entry)

        elif line[0] == 'Warning:' and line[1] == 'Vehicle' and line[3] == 'performs' and line[15] == 'red':
            entry = list()
            entry.append(log_time)
            line[18] = line[18].strip(',')
            line[18] = line[18].lstrip('(').rstrip(')')
            decelerate = float(line[18].split('=')[1])
            entry.append(decelerate)
            entry.append(line[2].strip('\''))
            feature_data.append(entry)

# interactive function
def get_options(args=None):
    parser = optparse.OptionParser()
    parser.add_option("-i", "--input", dest='input', help='input file')
    parser.add_option("-o", "--output", dest="output", help='output file')
    parser.add_option("--indir", dest="input_dir", help='directory of input files')
    parser.add_option("--outdir", dest="output_dir", help='directory of output files')

    (options, args) = parser.parse_args(args=args)
    if not (options.input or options.input_dir):
        parser.print_help()
        exit(1)
    if not (options.output or options.output_dir):
        parser.print_help()
        exit(1)
    return options

# main
def main(options=None):

    # Init
    feature_data = list()

    # Single processing
    if options.input and options.output:
        log_file = read_data(options.input, delimiter=' ')
        extract_feature(log_file, feature_data)
        output_dir = os.path.abspath('.')
        feature_header = ["date", "type", "vehicle", "vehicle"]
        write_csv(os.path.join(output_dir, options.output), feature_data, feature_header)

    # Batch processing
    else:
        for directory, subdirectories, files in os.walk(options.input_dir):
            for f in files:
                log_file = read_data(os.path.join(directory, f), delimiter=' ')
                date = f.split('.')[0].split('_')
                for i in range(1, 3):
                    date[i] = date[i].zfill(2)	# fill zero ahead of date if necessary
                log_time = ''.join(date[:-1])
                extract_feature(log_file, log_time, feature_data)

        output_dir = options.output_dir
        feature_header = ["date", "type", "vehicle", "vehicle"]
        write_csv(os.path.join(output_dir,  "feature_data.csv"), feature_data, feature_header)


if __name__ == '__main__':
    main(get_options())
